package com.atguigu.jvm;

import java.util.concurrent.TimeUnit;

public class FinalizeTest {

    public static FinalizeTest FINALIZE_TEST;

    public static void main(String[] args) throws InterruptedException {

        // 1、创建 FinalizeTest 对象
        FinalizeTest finalizeTest = new FinalizeTest();
        System.out.println("对象刚创建出来： " + finalizeTest.hashCode());

        // 2、把指向对象的引用置空
        finalizeTest = null;

        // 3、手动执行 GC 操作
        System.gc();

        System.out.println("finalizeTest = " + finalizeTest);

        // 4、查看静态变量
        // ※由于 Finalizer 线程优先级很低，所以让主线程睡一会儿，等待 Finalizer 线程执行完
        TimeUnit.SECONDS.sleep(1);
        System.out.println("对象经历第一次GC： " + FINALIZE_TEST.hashCode());

        // 5、finalize() 方法在对象生命周期中，只能被执行一次
        FINALIZE_TEST = null;

        System.gc();

        // ※由于 Finalizer 线程优先级很低，所以让主线程睡一会儿，等待 Finalizer 线程执行完
        TimeUnit.SECONDS.sleep(1);
        System.out.println("对象经历第二次GC： " + FINALIZE_TEST.hashCode());
    }

    @Override
    protected void finalize() throws Throwable {
        // 调用 finalize()  方法的线程名称：Finalizer
        // Finalizer 线程优先级很低
        System.out.println(Thread.currentThread().getName() + " 调用了finalize()方法！");

        // 为了让当前对象逃过 GC，给它一个引用
        // 但是局部变量不行，因为当前方法一旦结束，局部变量也就释放了，到那时当前对象还是没有引用指向它
        FinalizeTest finalizeTest = this;
        System.out.println("Finalizer 线程内： " + finalizeTest.hashCode());

        // 使用静态变量就可以了，静态变量不会随着方法的结束而消失
        FINALIZE_TEST = this;
    }
}
